/*
 * Miccsnookersim, a snooker simulation with AI
 * Copyright (C) 2009 Enno Ruijters, Frans van den Heuvel, Yannick Thimister,
 * Ali B. Ozmen, Esther Verhoef, Achim Leydecker
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

import java.awt.Color;
import java.util.concurrent.atomic.*;

public class Simulation
{
	private Table table;
	private Display display;

	public Simulation(Table t, Display d)
	{
		table = t;
		display = d;
	}

	public Simulation(Table t)
	{
		this(t, null);
	}

	public void performShot(Cue shot, boolean doDisplay,
	                        AtomicBoolean withNoise, boolean doReplace)
	{
		Ball cueBall = null;
		boolean noise = withNoise.get();

		for (Ball b : table.getBalls())
			if (b.getColor() == Color.WHITE)
				cueBall = b;
		
		table.getGameLogic().shotBegin();
		Physics.cueShot(shot, cueBall, noise);
		table.makeBallMoving(cueBall);
		while (table.areBallsMoving()) {
			long initialTime = System.currentTimeMillis();
			if (doDisplay)
				display.drawTable();
			table.advanceTime(0.01, noise);
			long sleepTime = (initialTime + 10)
			                 - System.currentTimeMillis();
			if (doDisplay) {
				try {
					Thread.sleep(sleepTime);
				} catch (Exception e) {	}
			}
		}
		if (doDisplay)
			display.drawTable();
                // turn of the cue shot here
		table.getGameLogic().shotEnd(doReplace);
		if (display != null)
			display.drawTable();
                // enable cue shot again after there is checked that the white ball
                // is on the table or placed back on the table... but how...
	}
	
	public void performShot(Cue shot, boolean doDisplay, boolean withNoise)
	{
		performShot(shot, doDisplay, new AtomicBoolean(withNoise), false);
	}
}

/*	The radius of the balls is 2.625, so diameter is 5.25.
	The balls cannot touch each other in the beginning of the game,
	so there is a space of 0.5 between the balls.
	Because the red balls lay in a V-order, a 0.5 space is too much.
	That is why the +1, per row comes in handy.
*/
